package com.restkeeper.controller.store;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.restkeeper.response.page.PageVO;
import com.restkeeper.store.dto.CreditDTO;
import com.restkeeper.store.entity.Credit;
import com.restkeeper.store.entity.CreditCompanyUser;
import com.restkeeper.store.entity.CreditLogs;
import com.restkeeper.store.entity.CreditRepayment;
import com.restkeeper.store.service.ICreditLogsService;
import com.restkeeper.store.service.ICreditRepaymentService;
import com.restkeeper.store.service.ICreditService;
import com.restkeeper.utils.SystemCode;
import com.restkeeper.vo.store.CreditExportVO;
import com.restkeeper.vo.store.CreditRepaymentVO;
import com.restkeeper.vo.store.CreditVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Api(tags = { "挂账管理" })
@RestController
@RequestMapping("/credit")
public class CreditController {

    @Reference(version = "1.0.0", check=false)
    private ICreditService creditService;

    @Reference(version = "1.0.0", check=false)
    private ICreditLogsService creditLogsService;

    @Reference(version = "1.0.0", check=false)
    private ICreditRepaymentService creditRepaymentService;

    /**
     * 查询分页数据及统计信息
     */
    @ApiOperation(value = "分页查询挂账列表信息")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "page", value = "当前页码", required = false, dataType = "Long"),
            @ApiImplicitParam(paramType = "path", name = "pageSize", value = "分页大小", required = false, dataType = "Long"),
            @ApiImplicitParam(paramType = "path", name = "name", value = "挂账人姓名名称", required = false, dataType = "String") })
    @GetMapping(value = "/pageList/{page}/{pageSize}")
    public PageVO<CreditDTO> findListByPage(
            @PathVariable Long page, @PathVariable Long pageSize, @RequestParam(value = "name", required = false) String name) {

        return new PageVO<>(creditService.queryPageByName(page, pageSize, name));
    }

    /**
     * 分页查询挂账订单明细
     */
    @ApiOperation(value = "分页查询挂账订单明细")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "page", value = "当前页码", required = false, dataType = "Long"),
            @ApiImplicitParam(paramType = "path", name = "pageSize", value = "分页大小", required = false, dataType = "Long"),
            @ApiImplicitParam(paramType = "path", name = "creditId", value = "挂账id", required = true, dataType = "String") })
    @GetMapping(value = "/creditLog/{page}/{pageSize}/{creditId}")
    public PageVO<CreditLogs> getCreditLogPageList(
            @PathVariable Long page,
            @PathVariable Long pageSize,
            @PathVariable String creditId,
            @RequestParam("startTime") @DateTimeFormat(pattern = "yyyy-MM-dd") Date startTime,
            @RequestParam("endTime") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime
            ) {

        return new PageVO<>(creditLogsService.queryPageByCreditId(page, pageSize, creditId, startTime, endTime));
    }

    /**
     * 根据id查询挂账详情
     */
    @ApiOperation(value = "查询挂账详情")
    @ApiImplicitParam(paramType="path", name = "id", value = "主键", required = true, dataType = "String")
    @GetMapping(value = "/{id}")
    public CreditDTO getById(@PathVariable String id){

        return creditService.getCreditById(id);
    }

    /**
     * 挂账还款
     */
    @ApiOperation(value = "挂账还款")
    @PostMapping("/repayment")
    public boolean repayment(@RequestBody CreditRepaymentVO creditRepaymentVO){

        // todo: 挂账还款 参考代码后修改
        CreditRepayment creditRepayment = new CreditRepayment();
        BeanUtils.copyProperties(creditRepaymentVO,creditRepayment);

        return creditRepaymentService.repayment(creditRepayment);
    }

    /**
     * 新增挂账
     */
    @ApiOperation(value = "新增挂账")
    @PostMapping(value = "/add")
    public boolean addCredit(@RequestBody CreditVO creditVO){

        // todo: 新增挂账 参考代码后修改
        // CreditVO->转化成 Credit
        Credit credit = new Credit();
        BeanUtils.copyProperties(creditVO, credit,"users");

        if (creditVO.getCreditType() == SystemCode.CREDIT_TYPE_COMPANY &&
                creditVO.getUsers() != null && !creditVO.getUsers().isEmpty()){

            // List<CreditCompanyUserVO> 转换成 List<CreditCompanyUser>
            List<CreditCompanyUser> companyUserList = new ArrayList<>();
            creditVO.getUsers().forEach(u -> {
                CreditCompanyUser creditCompany = new CreditCompanyUser();
                BeanUtils.copyProperties(u, creditCompany);
                companyUserList.add(creditCompany);
            });
            return creditService.addCredit(credit,companyUserList);
        }

        return creditService.addCredit(credit,null);
    }

    /**
     * 修改挂账
     */
    @ApiOperation(value = "修改挂账")
    @ApiImplicitParam(paramType="path", name = "id", value = "主键", required = true, dataType = "String")
    @PutMapping("/update/{id}")
    public boolean update(@PathVariable String id, @RequestBody CreditVO creditVO){

        //CreditVO->转化成 Credit
        Credit credit = creditService.getById(id);
        BeanUtils.copyProperties(creditVO, credit, "users");

        if (creditVO.getCreditType() == SystemCode.CREDIT_TYPE_COMPANY &&
                creditVO.getUsers() != null && !creditVO.getUsers().isEmpty()){

            // List<CreditCompanyUserVO> 转换成 List<CreditCompanyUser>
            List<CreditCompanyUser> companyUserList = new ArrayList<>();
            creditVO.getUsers().forEach(u -> {
                CreditCompanyUser creditCompany = new CreditCompanyUser();
                BeanUtils.copyProperties(u, creditCompany);
                companyUserList.add(creditCompany);
            });
            return creditService.updateCredit(credit,companyUserList);
        }

        return creditService.updateCredit(credit,null);
    }

    /**
     * 停用/启用挂账
     */
    @ApiOperation(value = "停用/启用 接口")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "id", value = "主键", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "path", name = "status", value = "状态", required = true, dataType = "Integer")})
    @PutMapping(value = "/update/{id}/status/{status}")
    public boolean disabled(@PathVariable String id, @PathVariable Integer status) {

        Credit credit = creditService.getById(id);
        credit.setStatus(status);

        return creditService.updateById(credit);
    }

    /**
     * 删除挂账
     */
    @ApiOperation(value = "删除挂账")
    @ApiImplicitParam(paramType="path", name = "id", value = "主键", required = true, dataType = "String")
    @DeleteMapping("/delete/{id}")
    public boolean delete(@PathVariable String id){

        return creditService.removeById(id);
    }

    /**
     * 挂账数据导出
     */
    @ApiOperation(value = "挂账数据导出")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "creditId", value = "挂账id", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "path", name = "start", value = "开始时间", required = true, dataType = "Date"),
            @ApiImplicitParam(paramType = "path", name = "end", value = "结束时间", required = true, dataType = "Date") })
    @GetMapping("/export/creditId/{creditId}/start/{start}/end/{end}")
    public void export(
            HttpServletResponse response,
            @PathVariable String creditId,
            @PathVariable("start") @DateTimeFormat(pattern = "yyyy-MM-dd") Date startTime,
            @PathVariable("end") @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime) throws IOException {

        // 数据集，存放显示的数
        IPage<CreditLogs> creditLogsIPage = creditLogsService.queryPageByCreditId(1, 500, creditId, startTime, endTime);
        List<CreditLogs> creditLogsList = creditLogsIPage.getRecords();
        List<CreditExportVO> creditExportVOList = new ArrayList<>();
        // 对象拷贝操作
        if (creditLogsList.size() > 0) {
            creditExportVOList = creditLogsList.stream().map( c -> {
                CreditExportVO vo = new CreditExportVO();
                BeanUtils.copyProperties(c, vo, "creditType");
                vo.setCreditType(c.getCreditType() == SystemCode.CREDIT_TYPE_COMPANY ?
                        "公司" : "个人");
                return vo;
            }).collect(Collectors.toList());
        }
        // log.error(creditLogsList.toString());
        // log.error(creditExportVOList.toString());

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("订单明细导出", "utf-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        // 设置文件名
        EasyExcel.write(response.getOutputStream(),CreditExportVO.class).excelType(ExcelTypeEnum.XLSX).sheet("订单明细").doWrite(creditExportVOList);
    }
}
